package com.scheduling.product.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.scheduling.common.exception.BusinessException;
import com.scheduling.product.dto.ProductDTO;
import com.scheduling.product.dto.ProductQueryDTO;
import com.scheduling.product.entity.Product;
import com.scheduling.product.mapper.ProductMapper;
import com.scheduling.product.service.ProductService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * 产品业务层实现类
 *
 * @author 开发团队
 * @since 2025-05-29
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> implements ProductService {

    private final ProductMapper productMapper;

    @Override
    public IPage<Product> getProductPage(ProductQueryDTO queryDTO) {
        log.info("分页查询产品列表，查询条件：{}", queryDTO);
        Page<Product> page = new Page<>(queryDTO.getPageNum(), queryDTO.getPageSize());
        return productMapper.selectProductPage(page, queryDTO);
    }

    @Override
    public Product getProductById(String productId) {
        log.info("根据ID查询产品：{}", productId);
        if (StrUtil.isBlank(productId)) {
            throw new BusinessException("产品ID不能为空");
        }
        Product product = productMapper.selectById(productId);
        if (product == null) {
            throw new BusinessException("产品不存在");
        }
        return product;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean addProduct(ProductDTO productDTO) {
        log.info("添加产品：{}", productDTO);

        // 检查产品名称是否已存在
        if (checkProductNameExists(productDTO.getProductName(), null)) {
            throw new BusinessException("产品名称已存在");
        }

        Product product = new Product();
        BeanUtil.copyProperties(productDTO, product);

        boolean result = save(product);
        if (result) {
            log.info("添加产品成功，产品ID：{}", product.getProductId());
        }
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateProduct(ProductDTO productDTO) {
        log.info("更新产品：{}", productDTO);

        if (StrUtil.isBlank(productDTO.getProductId())) {
            throw new BusinessException("产品ID不能为空");
        }

        // 检查产品是否存在
        Product existProduct = productMapper.selectById(productDTO.getProductId());
        if (existProduct == null) {
            throw new BusinessException("产品不存在");
        }

        // 检查产品名称是否已存在（排除当前产品）
        if (checkProductNameExists(productDTO.getProductName(), productDTO.getProductId())) {
            throw new BusinessException("产品名称已存在");
        }

        Product product = new Product();
        BeanUtil.copyProperties(productDTO, product);

        boolean result = updateById(product);
        if (result) {
            log.info("更新产品成功，产品ID：{}", product.getProductId());
        }
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteProduct(String productId) {
        log.info("删除产品：{}", productId);

        if (StrUtil.isBlank(productId)) {
            throw new BusinessException("产品ID不能为空");
        }

        // 检查产品是否存在
        Product product = productMapper.selectById(productId);
        if (product == null) {
            throw new BusinessException("产品不存在");
        }

        // 检查产品是否被订单项引用
        int orderItemCount = productMapper.countOrderItemsByProductId(productId);
        if (orderItemCount > 0) {
            throw new BusinessException("删除失败：该产品正在被 " + orderItemCount + " 个订单项引用，请先删除相关订单或订单项");
        }

        // 检查产品是否有工单引用
        int workOrderCount = productMapper.countWorkOrdersByProductId(productId);
        if (workOrderCount > 0) {
            throw new BusinessException("删除失败：该产品正在被 " + workOrderCount + " 个工单引用，请先删除相关工单");
        }

        // 检查产品是否有库存记录
        int inventoryCount = productMapper.countInventoryByProductId(productId);
        if (inventoryCount > 0) {
            throw new BusinessException("删除失败：该产品存在库存记录，请先删除相关库存记录");
        }

        // 检查产品是否有工艺路线
        int processRouteCount = productMapper.countProcessRoutesByProductId(productId);
        if (processRouteCount > 0) {
            throw new BusinessException("删除失败：该产品存在工艺路线，请先删除相关工艺路线");
        }

        boolean result = removeById(productId);
        if (result) {
            log.info("删除产品成功，产品ID：{}", productId);
        }
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteProducts(List<String> productIds) {
        log.info("批量删除产品，数量：{}", productIds.size());

        if (productIds == null || productIds.isEmpty()) {
            throw new BusinessException("产品ID列表不能为空");
        }

        for (String productId : productIds) {
            deleteProduct(productId);
        }
        return true;
    }

    @Override
    public List<Product> getAllProducts() {
        log.info("获取所有产品列表");
        LambdaQueryWrapper<Product> wrapper = new LambdaQueryWrapper<>();
        wrapper.select(
                Product::getProductId,
                Product::getProductName,
                Product::getDescription,
                Product::getCreateTime,
                Product::getUpdateTime
        );
        wrapper.orderByAsc(Product::getProductName);
        return productMapper.selectList(wrapper);
    }

    @Override
    public boolean checkProductNameExists(String productName, String excludeId) {
        if (StrUtil.isBlank(productName)) {
            return false;
        }
        Integer count = productMapper.checkProductNameExists(productName, excludeId);
        return count != null && count > 0;
    }
} 